<template>
  <div
    class="screenshot-overlay"
    @mousedown="handleMouseDown"
    @mousemove="handleMouseMove"
    @mouseup="handleMouseUp"
  >
    <!-- 全屏遮罩层（未开始框选时显示） -->
    <div class="fullscreen-mask" v-show="!isDrawing && !hasSelection"></div>

    <!-- 遮罩层（四个矩形覆盖选区外的区域） -->
    <div class="mask-layer" v-show="isDrawing || hasSelection">
      <!-- 上方遮罩 -->
      <div class="mask-top" :style="maskTopStyle"></div>
      <!-- 左侧遮罩 -->
      <div class="mask-left" :style="maskLeftStyle"></div>
      <!-- 右侧遮罩 -->
      <div class="mask-right" :style="maskRightStyle"></div>
      <!-- 下方遮罩 -->
      <div class="mask-bottom" :style="maskBottomStyle"></div>
    </div>

    <!-- 选区框 -->
    <div
      id="selection"
      :style="selectionStyle"
      :class="{ draggable: hasSelection && !isDrawing }"
      v-show="isDrawing || hasSelection"
      @mousedown="handleSelectionMouseDown"
    >
      <!-- 调整手柄 -->
      <div
        v-for="handle in resizeHandles"
        :key="handle.name"
        :class="['resize-handle', handle.name]"
        :style="{ ...handle.style, cursor: handle.cursor }"
        @mousedown.stop="handleResizeStart($event, handle.name)"
        v-show="hasSelection && !isDrawing"
      ></div>
    </div>

    <!-- 尺寸标签 -->
    <div
      id="size-label"
      :style="sizeLabelStyle"
      v-show="isDrawing || hasSelection"
    >
      {{ sizeLabelText }}
    </div>

    <!-- 工具栏 -->
    <div id="toolbar" :style="toolbarStyle" v-show="hasSelection && !isDrawing">
      <button
        class="toolbar-btn"
        @click="handleCancel"
        :disabled="isProcessing"
      >
        取消
      </button>
      <button class="toolbar-btn" @click="handlePin" :disabled="isProcessing">
        {{ isProcessing ? "处理中..." : "贴图" }}
      </button>
      <button class="toolbar-btn" @click="handleCopy" :disabled="isProcessing">
        {{ isProcessing ? "处理中..." : "复制" }}
      </button>
      <button
        class="toolbar-btn primary"
        @click="handleDownload"
        :disabled="isProcessing"
      >
        {{ isProcessing ? "处理中..." : "下载" }}
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from "vue";
import { invoke } from "@tauri-apps/api/core";

// 状态管理
const isDrawing = ref(false);
const isResizing = ref(false);
const isDragging = ref(false); // 是否正在拖动选区
const isProcessing = ref(false); // 防止重复点击

const resizeHandle = ref<string | null>(null);
const borderRadius = ref(0); // 圆角大小配置
// 起始点（鼠标按下时的坐标）
const startX = ref(0); // 起始X坐标
const startY = ref(0); // 起始Y坐标

// 当前点（鼠标移动时的坐标）
const currentX = ref(0); // 当前X坐标
const currentY = ref(0); // 当前Y坐标

// 选区左上角坐标及尺寸（确定后的选区）
const selectionX = ref(0); // 选区左上X坐标
const selectionY = ref(0); // 选区左上Y坐标
const selectionWidth = ref(0); // 选区宽度
const selectionHeight = ref(0); // 选区高度
const dragStartX = ref(0); // 拖动开始时的鼠标X坐标
const dragStartY = ref(0); // 拖动开始时的鼠标Y坐标
const dragOffsetX = ref(0); // 拖动时的X偏移
const dragOffsetY = ref(0); // 拖动时的Y偏移

// 计算属性
const hasSelection = computed(
  () => selectionWidth.value > 10 && selectionHeight.value > 10
);

const selectionStyle = computed(() => {
  const left = Math.min(startX.value, currentX.value);
  const top = Math.min(startY.value, currentY.value);
  const width = Math.abs(currentX.value - startX.value);
  const height = Math.abs(currentY.value - startY.value);

  if (hasSelection.value && !isDrawing.value) {
    return {
      left: `${selectionX.value}px`,
      top: `${selectionY.value}px`,
      width: `${selectionWidth.value}px`,
      height: `${selectionHeight.value}px`,
      borderRadius: `${borderRadius.value}px`,
    };
  }

  return {
    left: `${left}px`,
    top: `${top}px`,
    width: `${width}px`,
    height: `${height}px`,
    borderRadius: `${borderRadius.value}px`,
  };
});

// 遮罩层样式计算
const maskTopStyle = computed(() => {
  const top =
    hasSelection.value && !isDrawing.value
      ? selectionY.value
      : Math.min(startY.value, currentY.value);

  return {
    left: "0",
    top: "0",
    width: "100vw",
    height: `${top}px`,
  };
});

const maskLeftStyle = computed(() => {
  const left =
    hasSelection.value && !isDrawing.value
      ? selectionX.value
      : Math.min(startX.value, currentX.value);
  const top =
    hasSelection.value && !isDrawing.value
      ? selectionY.value
      : Math.min(startY.value, currentY.value);
  const height =
    hasSelection.value && !isDrawing.value
      ? selectionHeight.value
      : Math.abs(currentY.value - startY.value);

  return {
    left: "0",
    top: `${top}px`,
    width: `${left}px`,
    height: `${height}px`,
  };
});

const maskRightStyle = computed(() => {
  const left =
    hasSelection.value && !isDrawing.value
      ? selectionX.value
      : Math.min(startX.value, currentX.value);
  const top =
    hasSelection.value && !isDrawing.value
      ? selectionY.value
      : Math.min(startY.value, currentY.value);
  const width =
    hasSelection.value && !isDrawing.value
      ? selectionWidth.value
      : Math.abs(currentX.value - startX.value);
  const height =
    hasSelection.value && !isDrawing.value
      ? selectionHeight.value
      : Math.abs(currentY.value - startY.value);

  return {
    left: `${left + width}px`,
    top: `${top}px`,
    width: `calc(100vw - ${left + width}px)`,
    height: `${height}px`,
  };
});

const maskBottomStyle = computed(() => {
  const top =
    hasSelection.value && !isDrawing.value
      ? selectionY.value
      : Math.min(startY.value, currentY.value);
  const height =
    hasSelection.value && !isDrawing.value
      ? selectionHeight.value
      : Math.abs(currentY.value - startY.value);

  return {
    left: "0",
    top: `${top + height}px`,
    width: "100vw",
    height: `calc(100vh - ${top + height}px)`,
  };
});

const sizeLabelText = computed(() => {
  const dpr = window.devicePixelRatio;
  let width, height;

  if (hasSelection.value && !isDrawing.value) {
    width = Math.round(selectionWidth.value * dpr);
    height = Math.round(selectionHeight.value * dpr);
  } else {
    width = Math.round(Math.abs(currentX.value - startX.value) * dpr);
    height = Math.round(Math.abs(currentY.value - startY.value) * dpr);
  }

  return `${width} × ${height}`;
});

const sizeLabelStyle = computed(() => {
  let left, top, width, height;

  if (hasSelection.value && !isDrawing.value) {
    left = selectionX.value;
    top = selectionY.value;
    width = selectionWidth.value;
    height = selectionHeight.value;
  } else {
    left = Math.min(startX.value, currentX.value);
    top = Math.min(startY.value, currentY.value);
    width = Math.abs(currentX.value - startX.value);
    height = Math.abs(currentY.value - startY.value);
  }

  let labelX = left + width / 2;
  let labelY = top - 30;

  if (labelY < 10) {
    labelY = top + height + 10;
  }

  return {
    left: `${labelX}px`,
    top: `${labelY}px`,
    transform: "translateX(-50%)",
  };
});

const toolbarStyle = computed(() => {
  if (!hasSelection.value) return { display: "none" };

  const rect = {
    left: selectionX.value,
    top: selectionY.value,
    width: selectionWidth.value,
    height: selectionHeight.value,
    right: selectionX.value + selectionWidth.value,
    bottom: selectionY.value + selectionHeight.value,
  };

  // 工具栏宽度约 220px，高度约 40px
  const toolbarWidth = 220;
  const toolbarHeight = 40;
  const margin = 10;

  let toolbarX, toolbarY;

  // 1. 优先放在选区下方外部，水平居中于选区
  toolbarX = rect.left + (rect.width - toolbarWidth) / 2;
  toolbarY = rect.bottom + margin;

  // 如果下方位置超出屏幕，则尝试放在选区上方外部
  if (toolbarY + toolbarHeight > window.innerHeight) {
    toolbarY = rect.top - toolbarHeight - margin;
  }

  // 如果上方还不行（比如选区贴着顶部，下方空间也没了），则放在选区内部底部居中
  if (toolbarY < margin || rect.height < toolbarHeight + margin * 2) {
    toolbarY = rect.top + rect.height - toolbarHeight - margin;
    if (toolbarY < rect.top + margin) {
      toolbarY = rect.top + (rect.height - toolbarHeight) / 2;
    }
  }

  // 水平限制，确保不超出左右边界
  toolbarX = Math.max(
    margin,
    Math.min(toolbarX, window.innerWidth - toolbarWidth - margin)
  );
  toolbarY = Math.max(
    margin,
    Math.min(toolbarY, window.innerHeight - toolbarHeight - margin)
  );

  return {
    left: `${toolbarX}px`,
    top: `${toolbarY}px`,
  };
});

// 调整手柄配置
const resizeHandles = computed(() => {
  if (!hasSelection.value) return [];

  const handles = [
    { name: "nw", cursor: "nw-resize" },
    { name: "n", cursor: "n-resize" },
    { name: "ne", cursor: "ne-resize" },
    { name: "w", cursor: "w-resize" },
    { name: "e", cursor: "e-resize" },
    { name: "sw", cursor: "sw-resize" },
    { name: "s", cursor: "s-resize" },
    { name: "se", cursor: "se-resize" },
  ];

  return handles.map((handle) => {
    let style: any = {};

    switch (handle.name) {
      case "nw":
        style = { top: "-4px", left: "-4px" };
        break;
      case "n":
        style = { top: "-4px", left: "50%", marginLeft: "-4px" };
        break;
      case "ne":
        style = { top: "-4px", right: "-4px" };
        break;
      case "w":
        style = { top: "50%", left: "-4px", marginTop: "-4px" };
        break;
      case "e":
        style = { top: "50%", right: "-4px", marginTop: "-4px" };
        break;
      case "sw":
        style = { bottom: "-4px", left: "-4px" };
        break;
      case "s":
        style = { bottom: "-4px", left: "50%", marginLeft: "-4px" };
        break;
      case "se":
        style = { bottom: "-4px", right: "-4px" };
        break;
    }

    return {
      ...handle,
      style,
    };
  });
});

// 鼠标事件处理
const handleMouseDown = async (e: MouseEvent) => {
  // 忽略工具栏按钮点击
  if ((e.target as HTMLElement).closest("#toolbar")) return;
  // 忽略调整手柄点击
  if ((e.target as HTMLElement).closest(".resize-handle")) return;
  // 忽略选区框点击（拖动在 handleSelectionMouseDown 中处理）
  if ((e.target as HTMLElement).closest("#selection")) return;

  // 关闭其他屏幕的遮罩窗口
  try {
    await invoke("close_other_overlays");
  } catch (error) {
    console.error("关闭其他遮罩窗口失败:", error);
  }

  isDrawing.value = true;
  startX.value = e.clientX;
  startY.value = e.clientY;
  currentX.value = e.clientX;
  currentY.value = e.clientY;
};

const handleMouseMove = (e: MouseEvent) => {
  if (isDragging.value) {
    handleDragMove(e);
  } else if (isResizing.value && resizeHandle.value) {
    handleResizeMove(e);
  } else if (isDrawing.value) {
    currentX.value = e.clientX;
    currentY.value = e.clientY;
  }
};

const handleMouseUp = () => {
  if (isDrawing.value) {
    isDrawing.value = false;

    const width = Math.abs(currentX.value - startX.value);
    const height = Math.abs(currentY.value - startY.value);

    // 选区太小则重置
    if (width < 10 || height < 10) {
      selectionX.value = 0;
      selectionY.value = 0;
      selectionWidth.value = 0;
      selectionHeight.value = 0;
      return;
    }

    // 保存选区
    selectionX.value = Math.min(startX.value, currentX.value);
    selectionY.value = Math.min(startY.value, currentY.value);
    selectionWidth.value = width;
    selectionHeight.value = height;
  }

  if (isResizing.value) {
    isResizing.value = false;
    resizeHandle.value = null;
  }

  if (isDragging.value) {
    isDragging.value = false;
  }
};

// 选区拖动处理
const handleSelectionMouseDown = (e: MouseEvent) => {
  // 如果点击的是调整手柄，不处理拖动
  if ((e.target as HTMLElement).closest(".resize-handle")) return;
  // 如果没有选区，不处理拖动
  if (!hasSelection.value) return;

  isDragging.value = true;
  dragStartX.value = e.clientX;
  dragStartY.value = e.clientY;
  dragOffsetX.value = 0;
  dragOffsetY.value = 0;
};

const handleDragMove = (e: MouseEvent) => {
  if (!isDragging.value) return;

  const deltaX = e.clientX - dragStartX.value;
  const deltaY = e.clientY - dragStartY.value;

  // 计算新位置
  let newX = selectionX.value + deltaX - dragOffsetX.value;
  let newY = selectionY.value + deltaY - dragOffsetY.value;

  // 限制在屏幕范围内
  newX = Math.max(0, Math.min(newX, window.innerWidth - selectionWidth.value));
  newY = Math.max(
    0,
    Math.min(newY, window.innerHeight - selectionHeight.value)
  );

  // 更新选区位置
  selectionX.value = newX;
  selectionY.value = newY;

  // 更新偏移量
  dragOffsetX.value = deltaX;
  dragOffsetY.value = deltaY;
};

// 调整大小处理
const handleResizeStart = (e: MouseEvent, handle: string) => {
  e.stopPropagation();
  isResizing.value = true;
  resizeHandle.value = handle;
  startX.value = selectionX.value;
  startY.value = selectionY.value;
  currentX.value = selectionX.value + selectionWidth.value;
  currentY.value = selectionY.value + selectionHeight.value;
};

const handleResizeMove = (e: MouseEvent) => {
  if (!resizeHandle.value) return;

  const handle = resizeHandle.value;
  let newX = selectionX.value;
  let newY = selectionY.value;
  let newWidth = selectionWidth.value;
  let newHeight = selectionHeight.value;

  if (handle.includes("n")) {
    const deltaY = e.clientY - startY.value;
    newY = selectionY.value + deltaY;
    newHeight = selectionHeight.value - deltaY;
    if (newHeight < 10) {
      newHeight = 10;
      newY = selectionY.value + selectionHeight.value - 10;
    }
  }

  if (handle.includes("s")) {
    newHeight = e.clientY - selectionY.value;
    if (newHeight < 10) newHeight = 10;
  }

  if (handle.includes("w")) {
    const deltaX = e.clientX - startX.value;
    newX = selectionX.value + deltaX;
    newWidth = selectionWidth.value - deltaX;
    if (newWidth < 10) {
      newWidth = 10;
      newX = selectionX.value + selectionWidth.value - 10;
    }
  }

  if (handle.includes("e")) {
    newWidth = e.clientX - selectionX.value;
    if (newWidth < 10) newWidth = 10;
  }

  selectionX.value = newX;
  selectionY.value = newY;
  selectionWidth.value = newWidth;
  selectionHeight.value = newHeight;
};

// 贴图功能
const handlePin = async () => {
  // 防止重复点击
  if (isProcessing.value) {
    return;
  }

  isProcessing.value = true;

  const dpr = window.devicePixelRatio;
  const borderWidth = 2; // 边框宽度

  // 计算逻辑坐标（用于窗口定位）和物理像素坐标（用于截图）
  const logicalX = selectionX.value + borderWidth;
  const logicalY = selectionY.value + borderWidth;
  const logicalWidth = selectionWidth.value - borderWidth * 2;
  const logicalHeight = selectionHeight.value - borderWidth * 2;

  // 物理像素坐标（用于截图）
  const captureData = {
    x: Math.round(logicalX * dpr),
    y: Math.round(logicalY * dpr),
    width: Math.round(logicalWidth * dpr),
    height: Math.round(logicalHeight * dpr),
    // 逻辑坐标（用于窗口定位）
    logicalX: Math.round(logicalX),
    logicalY: Math.round(logicalY),
    logicalWidth: Math.round(logicalWidth),
    logicalHeight: Math.round(logicalHeight),
  };

  console.log("贴图区域:", captureData);

  // 立即关闭遮罩窗口，给用户即时反馈
  invoke("close_overlay_window").catch(console.error);

  // 后台完成贴图创建
  try {
    await invoke("pin_selected_area", captureData);
    console.log("贴图窗口已创建");
  } catch (error) {
    console.error("贴图失败:", error);
  }
};

// 下载截图
const handleDownload = async () => {
  // 防止重复点击
  if (isProcessing.value) {
    return;
  }

  isProcessing.value = true;

  const dpr = window.devicePixelRatio;
  const borderWidth = 2; // 边框宽度

  // 排除边框：坐标向内偏移 borderWidth，尺寸减少 2 * borderWidth
  const captureData = {
    x: Math.round((selectionX.value + borderWidth) * dpr),
    y: Math.round((selectionY.value + borderWidth) * dpr),
    width: Math.round((selectionWidth.value - borderWidth * 2) * dpr),
    height: Math.round((selectionHeight.value - borderWidth * 2) * dpr),
  };

  console.log("截图区域:", captureData);

  // 立即关闭窗口，给用户即时反馈
  invoke("close_overlay_window").catch(console.error);

  // 后台完成截图（实时截图）
  try {
    const filePath = await invoke<string>("capture_selected_area", captureData);
    console.log("实时截图已保存到:", filePath);
  } catch (error) {
    console.error("实时截图失败:", error);
  }
};

// 复制截图到剪贴板
const handleCopy = async () => {
  // 防止重复点击
  if (isProcessing.value) {
    return;
  }

  isProcessing.value = true;

  const dpr = window.devicePixelRatio;
  const borderWidth = 2; // 边框宽度

  // 排除边框：坐标向内偏移 borderWidth，尺寸减少 2 * borderWidth
  const captureData = {
    x: Math.round((selectionX.value + borderWidth) * dpr),
    y: Math.round((selectionY.value + borderWidth) * dpr),
    width: Math.round((selectionWidth.value - borderWidth * 2) * dpr),
    height: Math.round((selectionHeight.value - borderWidth * 2) * dpr),
  };

  console.log("复制截图区域:", captureData);

  // 立即关闭窗口，给用户即时反馈
  invoke("close_overlay_window").catch(console.error);

  // 后台完成复制（实时截图）
  try {
    await invoke("copy_selected_area_to_clipboard", captureData);
    console.log("实时截图已复制到剪贴板");
  } catch (error) {
    console.error("实时截图复制失败:", error);
  }
};

// 取消截图
const handleCancel = async () => {
  try {
    await invoke("close_overlay_window");
  } catch (error) {
    console.error("关闭遮罩窗口失败:", error);
  }
};

// 键盘事件处理
const handleKeyDown = async (event: KeyboardEvent) => {
  if (event.key === "Escape") {
    await handleCancel();
  }
};

onMounted(() => {
  window.addEventListener("keydown", handleKeyDown);
  window.focus();

  // 获取圆角配置
  invoke<{ border_radius: number }>("get_screenshot_config")
    .then((config) => {
      borderRadius.value = config.border_radius;
    })
    .catch((e) => {
      console.error("Failed to load screenshot config:", e);
    });
});

onUnmounted(() => {
  window.removeEventListener("keydown", handleKeyDown);
});
</script>

<style lang="scss" scoped>
.screenshot-overlay {
  width: 100vw;
  height: 100vh;
  cursor: crosshair;
  background: transparent;
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  user-select: none;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.fullscreen-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

.mask-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.mask-top,
.mask-left,
.mask-right,
.mask-bottom {
  position: absolute;
  background: rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

#selection {
  position: absolute;
  border: 2px solid #0a84ff;
  pointer-events: none;
  background: transparent;

  &.draggable {
    pointer-events: auto;
    cursor: move;
  }
}

#size-label {
  position: absolute;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 12px;
  pointer-events: none;
  font-weight: 500;
  white-space: nowrap;
}

#toolbar {
  position: absolute;
  background: rgba(50, 50, 50, 0.95);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  padding: 6px;
  border-radius: 6px;
  display: flex;
  gap: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  pointer-events: auto;
}

.toolbar-btn {
  background: transparent;
  border: none;
  color: white;
  padding: 6px 14px;
  cursor: pointer;
  border-radius: 4px;
  font-size: 13px;
  transition: background 0.15s;
  font-weight: 500;
  pointer-events: auto;

  &:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.15);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  &.primary {
    background: #0a84ff;

    &:hover:not(:disabled) {
      background: #0077ed;
    }
  }
}

.resize-handle {
  position: absolute;
  width: 8px;
  height: 8px;
  background: white;
  border: 1.5px solid #0a84ff;
  border-radius: 50%;
  z-index: 10;
  pointer-events: auto;

  &.nw {
    cursor: nw-resize;
  }
  &.n {
    cursor: n-resize;
  }
  &.ne {
    cursor: ne-resize;
  }
  &.w {
    cursor: w-resize;
  }
  &.e {
    cursor: e-resize;
  }
  &.sw {
    cursor: sw-resize;
  }
  &.s {
    cursor: s-resize;
  }
  &.se {
    cursor: se-resize;
  }
}
</style>
